﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;

namespace SpaceShip001
{
    class Camera
    {
        GraphicsDevice device;
        private Vector3 position;
        private float movingSpeed;
        private float rotatingSpeed;
        public Matrix view, projection, rotation;
        private float yawY = 0;
        private float pitchX = 0;
        private int oldX, oldY;
        private float currentScrollWheel, oldScrollWheel;

        public Camera(GraphicsDevice device, Vector3 cameraPosition, float movingSpeed, float rotatingSpeed)
        {
            this.device = device;
            position = cameraPosition;
            this.movingSpeed = movingSpeed;
            this.rotatingSpeed = rotatingSpeed;

            view = Matrix.CreateLookAt(cameraPosition, Vector3.Zero, Vector3.Up);
            projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, device.Viewport.AspectRatio, 0.1f, 1000.0f);

            ResetMouseCursor();
        }

        public void Update()
        {
            KeyboardState keyState = Keyboard.GetState();

            if (keyState.IsKeyDown(Keys.W))
            {
                Vector3 v = new Vector3(0, 0, -1) * movingSpeed;
                Move(v);
            }

            if (keyState.IsKeyDown(Keys.S))
            {
                Vector3 v = new Vector3(0, 0, 1) * movingSpeed;
                Move(v);
            }

            if (keyState.IsKeyDown(Keys.A))
            {
                Vector3 v = new Vector3(-1, 0, 0) * movingSpeed;
                Move(v);
            }

            if (keyState.IsKeyDown(Keys.D))
            {
                Vector3 v = new Vector3(1, 0, 0) * movingSpeed;
                Move(v);
            }

            if (keyState.IsKeyDown(Keys.Up))
            {
                Vector3 v = new Vector3(0, 1, 0) * movingSpeed;
                Move(v);
            }

            if (keyState.IsKeyDown(Keys.Down))
            {
                Vector3 v = new Vector3(0, -1, 0) * movingSpeed;
                Move(v);
            }


            pitchX = MathHelper.Clamp(pitchX, -1.5f, 1.5f);

            MouseState mState = Mouse.GetState();

            currentScrollWheel = mState.ScrollWheelValue;

            if (currentScrollWheel < oldScrollWheel)
            {
                Vector3 v = new Vector3(0, -1, 0) * movingSpeed * 8;
                Move(v);
            }

            if (currentScrollWheel > oldScrollWheel)
            {
                Vector3 v = new Vector3(0, 1, 0) * movingSpeed * 8;
                Move(v);
            }
            
            

            int dx = mState.X - oldX;
            int dy = mState.Y - oldY;

            yawY -= rotatingSpeed * dx;
            pitchX -= rotatingSpeed * dy;

            ResetMouseCursor();

            UpdateMatrices();

        }

        private void Move(Vector3 v)
        {
            Matrix yRotation = Matrix.CreateRotationY(yawY);
            v = Vector3.Transform(v, yRotation);
            position += v;
        }

        private void UpdateMatrices()
        {
            rotation = Matrix.CreateRotationX(pitchX) * Matrix.CreateRotationY(yawY);
            Vector3 transformedPreference = Vector3.Transform(new Vector3(0, 0, -1), rotation);
            Vector3 lookAt = position + transformedPreference;

            view = Matrix.CreateLookAt(position, lookAt, Vector3.Up);

        }

        private void ResetMouseCursor()
        {
            int centerX = device.Viewport.Width / 2;
            int centerY = device.Viewport.Height / 2;

            Mouse.SetPosition(centerX, centerY);

            oldX = centerX;
            oldY = centerY;
            oldScrollWheel = currentScrollWheel;
            
            
            

        }
    }
}
